package com.hsxshop.daoimpl;

import com.hsxshop.dao.BaseDao;

import com.hsxshop.model.Pagination;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.hibernate.transform.Transformers;


import javax.annotation.Resource;
import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by wangchongya on 17/5/8.
 */
public abstract class BaseDaoImpl<T> implements BaseDao<T> {

    private Class<T> clazz;
    private SessionFactory sf;

    @Resource(name="sf")
    public void setSf(SessionFactory sf) {
        this.sf = sf;
    }

    public BaseDaoImpl(){
        ParameterizedType type=(ParameterizedType)this.getClass().getGenericSuperclass();
        clazz=(Class)type.getActualTypeArguments()[0];
    }

    public int saveEntity(T t) {
        return Integer.parseInt(sf.getCurrentSession().save(t).toString());
    }

    public void updateEntity(T t) {
        sf.getCurrentSession().update(t);
    }

    public void saveOrUpdateEntity(T t) {
        sf.getCurrentSession().saveOrUpdate(t);
    }

    public void deleteEntity(T t) {
        sf.getCurrentSession().delete(t);
    }

    public T getEntity(Integer id) {

        T t=sf.getCurrentSession().get(clazz,id);
        return t;
    }
    public T getEntity(String hql, Object... objects){
        Query q=sf.getCurrentSession().createQuery(hql);
        if(null != objects){
            for (int i = 0; i < objects.length; i++) {
                q.setParameter(i,objects[i]);
            }
        }
        if(this.exitsByHQL(hql,objects)){
            return (T)q.uniqueResult();
        }
        return null;
    }




    public Map getMapByHQL(String hql, Object... objects){
        NativeQuery q=sf.getCurrentSession().createNativeQuery(hql);
//        Query q=sf.getCurrentSession().createQuery(hql);
        for (int i = 0; i < objects.length; i++) {
            q.setParameter(i,objects[i]);
        }
        List lists=q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
        if(lists.size()>0){
            return (Map)lists.get(0);
        }else{
            return null;
        }
    }

    public List<Map> getListMapByHQL(String hql, Object... objects){
        NativeQuery q=sf.getCurrentSession().createNativeQuery(hql);
        for (int i = 0; i < objects.length; i++) {
            q.setParameter(i,objects[i]);
        }

        List lists=q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
        return lists;
    }

    public List<Map> getListMapByHQL(Pagination pagination,String hql, Object... objects){
        NativeQuery q=sf.getCurrentSession().createNativeQuery(hql);
        for (int i = 0; i < objects.length; i++) {
            q.setParameter(i,objects[i]);
        }
        pagination.setAllRows(this.getRowsCountByHQL(hql,objects));
        pagination.setPageCounts();
        q.setFirstResult((pagination.getPageIndex()-1)*pagination.getPageSize());
        q.setMaxResults(pagination.getPageSize());

        List lists=q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();

        return lists;
    }

    public List<T> findByHQL(String hql, Object... objects) {
        Query q=sf.getCurrentSession().createQuery(hql);
        for (int i = 0; i < objects.length; i++) {
            q.setParameter(i,objects[i]);
        }
        return q.list();
    }

    public boolean exitsByHQL(String hql, Object... objects){
        Query q=sf.getCurrentSession().createQuery(hql);
        for (int i = 0; i < objects.length; i++) {
            q.setParameter(i,objects[i]);
        }
        if(q.list().size()>0) return true;
        return false;
    }

    public int execHQL(String hql, Object... objects) {
        Query q=sf.getCurrentSession().createQuery(hql);
        for (int i = 0; i < objects.length; i++) {
            q.setParameter(i,objects[i]);
        }
       return  q.executeUpdate();
    }

    public int getRowsCountByHQL(String hql, Object... objects){
        String[] strs=hql.split("FROM");
        String sql="select count(*) from";
        for(int i=1,len=strs.length;i<len;i++){
            sql+=strs[i].toString();
        }
        Query q=sf.getCurrentSession().createQuery(sql);
        if(null != objects){
            for (int i = 0; i < objects.length; i++) {
                q.setParameter(i,objects[i]);
            }
        }
        return Integer.parseInt(q.uniqueResult().toString());
    }


    public List<T>  findByHQLWithPagination(Pagination pagination, String hql, Object... objects){
        Query q=sf.getCurrentSession().createQuery(hql);
        if(null != objects){
            for (int i = 0; i < objects.length; i++) {
                q.setParameter(i,objects[i]);
            }
        }
        pagination.setAllRows(this.getRowsCountByHQL(hql,objects));
        pagination.setPageCounts();
        q.setFirstResult((pagination.getPageIndex()-1)*pagination.getPageSize());
        q.setMaxResults(pagination.getPageSize());
        List<T>list=q.list();
        return list;

    }

}
